<?php
/* --------------------------------------------------------------
   GMMeta.php 2023-06-19
   Gambio GmbH
   http://www.gambio.de
   Copyright (c) 2023 Gambio GmbH
   Released under the GNU General Public License (Version 2)
   [http://www.gnu.org/licenses/gpl-2.0.html]
   --------------------------------------------------------------
*/

use Doctrine\DBAL\Connection;
use Gambio\Core\Configuration\Services\ConfigurationService;

/*
 * 	class GMMeta 	
 */

class GMMeta_ORIGIN
{
	public    $gm_lang_id;
	public    $gm_lang_code;
	public    $gm_language_charset;
	public    $use_title;
	public    $show_title;
	public    $separator;
	public    $title;
	public    $output;
	protected $use_standard_title;
	protected $show_standard_title;
	protected $standard_title_separator;
	protected $standard_title;
    
    /**
     * @var ConfigurationService
     */
    protected $configurationService;
	
	
	/*
	 * 	class GMMeta
	 */
	public function __construct($p_output = true)
	{
		$this->output = $p_output;
		
		// get language
		if(!class_exists('language'))
		{
			require_once DIR_WS_CLASSES . 'language.php';
		}

		$lng = new language(xtc_input_validation($_SESSION['language_code'], 'char', ''));

		if(!empty($_SESSION['languages_id']))
		{
			$this->gm_lang_id = $_SESSION['languages_id'];
		}
		else
		{
			$this->gm_lang_id = $lng->language['id'];
		}

		$this->gm_lang_code = $lng->language['code'];
		$this->gm_language_charset = $lng->language['language_charset'];

		$this->use_standard_title = gm_get_conf('GM_TITLE_USE_STANDARD_META_TITLE');
		$this->show_standard_title = gm_get_conf('GM_TITLE_SHOW_STANDARD_META_TITLE');
		$this->standard_title_separator = gm_get_content('GM_TITLE_STANDARD_META_TITLE_SEPARATOR', $this->gm_lang_id);

		$t_standard_title = gm_get_content('GM_TITLE_STANDARD_META_TITLE', $this->gm_lang_id);
		
		if(empty($t_standard_title))
		{
			$t_standard_title = htmlspecialchars_wrapper(STORE_NAME);
		}
		else
		{
			$t_standard_title = htmlspecialchars_wrapper($t_standard_title);
		}
		
		$this->standard_title = $t_standard_title;

		return;
	}

	/*
	 * 	get metatags
	 */
	function get($cPath, $product)
	{
		$t_html = '';
		
		// get essential meta
		$t_html .= $this->get_base_meta();

		// get optional metatags
		$t_html .= $this->get_optional_meta($cPath, $product);

		// get content metatags
		$t_html .= $this->get_content_meta($cPath, $product);

		return $t_html;
	}

	/*
	 * 	get essential metatags
	 */
	public function get_base_meta()
	{
		$t_html = '<meta http-equiv="Content-Type" content="text/html; charset=' . $this->gm_language_charset . '" />' . "\n";
		
		$t_html .= "\t\t" . '<meta name="language" content="' . $this->gm_lang_code . '" />' . "\n";
		
		if($this->output)
		{
			echo $t_html;
		}

		return $t_html;
	}

	/*
	 * 	get metatags generated by content
	 */
	public function draw_page_title($p_content, $p_optional = '')
	{
		$t_page = '';
		$t_title = '';

		if(isset($_GET['page']) && empty($_GET['page']) === false)
		{
			$t_page = ' ' . GM_PAGE . ' ' . $_GET['page'];
		}

		if(empty($p_content) === false)
		{
			$t_title .= htmlspecialchars_wrapper($p_content) . $t_page;
		}
		else if(empty($p_optional) === false)
		{
			$t_title .= htmlspecialchars_wrapper($p_optional) . $t_page;
		}
		else
		{
			$t_title = htmlspecialchars_wrapper(STORE_NAME);
		}

		if((int)$this->use_standard_title === 1 && empty($this->standard_title) === false)
		{
			if($this->show_standard_title === 'before' || empty($this->show_standard_title))
			{
				$t_title = $this->standard_title . $this->standard_title_separator . $t_title;
			}
			else if($this->show_standard_title === 'after')
			{
				$t_title = $t_title . $this->standard_title_separator . $this->standard_title;
			}
		}

		$t_html = "\t\t" . '<title>' . trim($t_title) . '</title>' . "\n";

		if($this->output)
		{
			echo $t_html;
		}

		return $t_html;
	}

	/*
	 * 	get metatags generated by content
	 */
	public function draw_meta_tag($name, $content, $optional = '')
	{
		$t_html = '';

		if(empty($content) && !empty($optional))
		{
			$content = $optional;
		}

		if(!empty($content))
		{
			$t_html = "\t\t" . '<meta name="' . $name . '" content="' . htmlspecialchars_wrapper($content) . '" />' . "\n";
		}

		if($this->output)
		{
			echo $t_html;
		}

		return $t_html;
	}
	
	/*
	 * 	get OpenGraph metatags generated by content
	 */
	public function draw_ogmeta_tag($name, $content, $optional = '')
	{
		$t_html = '';
		
		if(empty($content) && !empty($optional))
		{
			$content = $optional;
		}
		
		if(!empty($content))
		{
			$t_html = "\t\t" . '<meta property="' . $name . '" content="' . htmlspecialchars_wrapper($content) . '" />' . "\n";
		}
		
		if($this->output)
		{
			echo $t_html;
		}
		
		return $t_html;
	}
	
	/*
	 * 	get metatags generated by content
	 */
	public function get_content_meta($cPath, $product)
	{
		$t_html = '';

		// handle products
		if((int)$product->pID !== 0)
		{
			$t_html .= $this->draw_meta_tag('keywords', $product->data['products_meta_keywords'] ?? '', gm_get_content('meta/keywords', $this->gm_lang_id));
			$t_html .= $this->draw_meta_tag('description', $product->data['products_meta_description'] ?? '', gm_get_content('meta/description', $this->gm_lang_id));
			$t_html .= $this->draw_page_title($product->data['products_meta_title'] ?? '', $product->data['products_name'] ?? '');
			
			/* Facebook Start */
			// set product image
			$t_product_image = '';
			
			if((string)($product->data['products_image'] ?? '') !== '')
			{
				$t_product_image = GM_HTTP_SERVER . DIR_WS_CATALOG . DIR_WS_INFO_IMAGES . $product->data['products_image'];
			}
			
			// set metatags
			$t_html_properties = "\t\t" . '<meta property="og:title" content="' . htmlentities_wrapper($product->data['products_name'] ?? '') . '" />' . "\n";
			$t_html_properties .= "\t\t" . '<meta property="og:site_name" content="' . htmlentities_wrapper(STORE_NAME) . '" />' . "\n";
			$t_html_properties .= "\t\t" . '<meta property="og:locale" content="' . $this->gm_lang_code . '_' . strtoupper($this->gm_lang_code) . '" />' . "\n";
			$t_html_properties .= "\t\t" . '<meta property="og:type" content="product" />' . "\n";
			
			if (!empty($product->data['products_meta_description'])) {
			    $products_description = $product->data['products_meta_description'];
            } elseif (!empty($product->data['products_short_description'])) {
                $products_description = $product->data['products_short_description'];
            } else {
                $products_description = $product->data['products_description'] ?? '';
            }
			$products_description = strip_tags($products_description);
			$products_description = htmlspecialchars($products_description);
			
			$products_description = preg_replace("/<p[^>]*>(\\[TAB:(.*?)\\])<\\/p>/", '$1', $products_description);
			$products_description = preg_split("/\\[TAB:(.*?)\\]/", $products_description, -1, PREG_SPLIT_DELIM_CAPTURE)[0];
			
			$products_description = strip_tags($products_description);
			
			$products_description = htmlspecialchars_wrapper(html_entity_decode_wrapper(html_entity_decode_wrapper($products_description)));
			
			if(strlen($products_description) > 250)
			{
				preg_match("/(?<product_description>.{0,250}\\b)/s",$products_description,$matches);
				$products_description = $matches['product_description'] . '...';
			}
			
			$t_html_properties .= "\t\t" . '<meta property="og:description" content="' . $products_description . '" />' . "\n";
			$t_html_properties .= "\t\t" . '<meta property="og:image" content="' . htmlentities_wrapper($t_product_image) . '" />' . "\n";
			
			$db     = StaticGXCoreLoader::getDatabaseQueryBuilder();
			$images = $db->select('image_name')
			             ->from('products_images')
			             ->where('products_id', $product->pID)
			             ->get()
			             ->result_array();
			
			foreach($images as $image)
			{
				$t_html_properties .= "\t\t" . '<meta property="og:image" content="' . GM_HTTP_SERVER . DIR_WS_CATALOG . DIR_WS_INFO_IMAGES . htmlentities_wrapper($image['image_name']) . '" />' . "\n";
			}
			
			$t_html .= $t_html_properties;
			
			if($this->output)
			{
				echo $t_html_properties;
			}

			// handle categories
		}
		else if(!empty($cPath))
		{
			$gm_cat_id = explode('_', $cPath);
			
			$db = StaticGXCoreLoader::getDatabaseQueryBuilder();
			$categoriesQuery = $db->select('cd.categories_meta_keywords, cd.categories_meta_description, cd.categories_meta_title, cd.categories_name')
			                      ->select('c.categories_image, c.categories_ogimage')
			                      ->from('categories c')
			                      ->join('categories_description cd',
			                             'cd.categories_id = c.categories_id AND cd.language_id = '
			                             . (int)$this->gm_lang_id)
			                      ->where('c.categories_id', (int)end($gm_cat_id))
			                      ->get();
			$categories_meta = $categoriesQuery->row_array();

			$ogImageUrl = GM_HTTP_SERVER . DIR_WS_CATALOG . DIR_WS_IMAGES . 'categories/og/' . $categories_meta['categories_ogimage'];
			
			$t_html .= $this->draw_meta_tag('keywords', $categories_meta['categories_meta_keywords'], gm_get_content('meta/keywords', $this->gm_lang_id));
			$t_html .= $this->draw_meta_tag('description', $categories_meta['categories_meta_description'], gm_get_content('meta/description', $this->gm_lang_id));
			$t_html .= $this->draw_ogmeta_tag('og:description', $categories_meta['categories_meta_description'], gm_get_content('meta/description', $this->gm_lang_id));
			$t_html .= $this->draw_ogmeta_tag('og:image', $ogImageUrl);
			$t_html .= $this->draw_ogmeta_tag('og:title', $categories_meta['categories_name']);
			$t_html .= $this->draw_ogmeta_tag('og:type', 'product.group');
			$t_html .= $this->draw_page_title($categories_meta['categories_meta_title'], $categories_meta['categories_name']);
			
			// handle contents
		}
		else if(strpos(gm_get_env_info('SCRIPT_NAME'), 'shop_content.php') !== false
		        || (strpos(gm_get_env_info('SCRIPT_NAME'), 'shop_content.php') === false && !is_object($cPath)
		            && empty($product->pID)))
		{
			$filename = basename(gm_get_env_info('SCRIPT_NAME'));
			
			// static php files, except contents
			if(!in_array($filename, ['shop_content.php', 'popup_content.php'], true) && strlen($filename) > 4
			   && substr($filename, -4) === '.php')
			{
				// get static seo url info from static seo urls
				$static_seo_url_content_query = xtc_db_query('
					SELECT * 
					FROM `static_seo_url_contents` s
					INNER JOIN `static_seo_urls` AS u ON (s.`static_seo_url_id` = u.`static_seo_url_id`)
					WHERE 
					 	u.`name` = "' . xtc_db_input($filename) . '" AND
					 	s.`language_id` = ' . (int)$this->gm_lang_id);
				
				$static_seo_url_content = xtc_db_fetch_array($static_seo_url_content_query, true);
				
				$title       = !empty($static_seo_url_content['title']) ? $static_seo_url_content['title'] : null;
				$keywords    = !empty($static_seo_url_content['keywords']) ? $static_seo_url_content['keywords'] : null;
				$description = !empty($static_seo_url_content['description']) ? $static_seo_url_content['description'] : null;
				
				if(!empty($_GET['manufacturers_id']))
				{
					$manu_query = xtc_db_query('SELECT `manufacturers_name` AS `name`
												FROM `manufacturers`
												WHERE `manufacturers_id` = ' . (int)$_GET['manufacturers_id']);
					
					$manu_meta = xtc_db_fetch_array($manu_query, true);
					
					$t_html .= $this->draw_page_title($manu_meta['name']);
					$title = $manu_meta['name'];
				}
				elseif($filename === 'products_new.php' && $title === null)
				{
					$t_html .= $this->draw_page_title(NAVBAR_TITLE_PRODUCTS_NEW);
					$title = NAVBAR_TITLE_PRODUCTS_NEW;
				}
				elseif($filename === 'specials.php' && $title === null)
				{
					$t_html .= $this->draw_page_title(NAVBAR_TITLE_SPECIALS);
					$title = NAVBAR_TITLE_SPECIALS;
				}
				else
				{
					$t_html .= $this->draw_page_title($title);
				}
                
                $t_html .= $this->draw_meta_tag('keywords', $keywords, gm_get_content('meta/keywords', $this->gm_lang_id));
                
                $t_html .= $this->draw_meta_tag('description', $description,
				                                gm_get_content('meta/description', $this->gm_lang_id));
				$t_html .= $this->draw_ogmeta_tag('og:title', $title);
				if(!empty($static_seo_url_content['opengraph_image']))
				{
					$ogImageUrl = GM_HTTP_SERVER . DIR_WS_CATALOG . DIR_WS_IMAGES . $static_seo_url_content['opengraph_image'];
					$t_html .= $this->draw_ogmeta_tag('og:image', $ogImageUrl);
				}
			}
			else
			{
				$contents_meta_query = xtc_db_query('SELECT
															`content_title`,
															`content_heading`,
															`contents_meta_title`,
															`contents_meta_keywords`,
															`contents_meta_description`,
															`opengraph_image`
														FROM ' . TABLE_CONTENT_MANAGER . '
														WHERE 
															`content_group` = ' . (int)$_GET['coID'] . ' AND
															`languages_id` = ' . (int)$this->gm_lang_id);
				
				$contents_meta = xtc_db_fetch_array($contents_meta_query, true);
				
				if(empty($contents_meta['content_heading']))
				{
					$contents_meta['content_heading'] = $contents_meta['content_title'];
				}
				
				$t_html .= $this->draw_page_title($contents_meta['contents_meta_title'],
				                                  $contents_meta['content_title']);
				$t_html .= $this->draw_ogmeta_tag('og:title', $contents_meta['contents_meta_title']);
				$t_html .= $this->draw_meta_tag('keywords', $contents_meta['contents_meta_keywords'],
				                                gm_get_content('meta/keywords', $this->gm_lang_id));
				$t_html .= $this->draw_meta_tag('description', $contents_meta['contents_meta_description'],
				                                gm_get_content('description', $this->gm_lang_id));
				$t_html .= $this->draw_ogmeta_tag('og:description', $contents_meta['contents_meta_description']);
				if(!empty($contents_meta['opengraph_image']))
				{
					$ogImageUrl = GM_HTTP_SERVER . DIR_WS_CATALOG . DIR_WS_IMAGES . rawurlencode($contents_meta['opengraph_image']);
					$t_html .= $this->draw_ogmeta_tag('og:image', $ogImageUrl);
				}
			}
		}

		return $t_html;
	}

	/*
	 *  get all optional metatags
	 */
	public function get_optional_meta($cPath, $product)
	{
        $configurationService  = $this->configurationService();
        $metaTagConfigurations = $this->additionalMetaConfigurationKeys();
        $gm_metatags           = [];
        
        foreach ($metaTagConfigurations as $key) {
            $configuration = $configurationService->findLanguageDependent($key, $this->gm_lang_code);
    
            // If we don't have a value for the current tag, we skip it in order not to render
            if ($configuration) {
                $gm_metatags[$key] = $configuration->value();
            }
        }
		
        $t_html = '';
		foreach ($gm_metatags as $gm_key => $gm_value) {
            $gm_key = str_replace('gm_configuration/meta/', '', $gm_key);
            
            if ($gm_key === 'keywords' || $gm_key === 'robots') {
                continue;
            }
		    
			$t_key_facebook = strpos($gm_key, 'facebook_') === 0;
			$t_is_product = !empty($product->pID);
			$t_get_fb_meta = true;
   
            if (($gm_key === 'description' && !empty($cPath)) ||
               ($gm_key === 'description' && $t_is_product) ||
               ($gm_key === 'description' && isset($_GET['coID'])) ||
               (strpos(gm_get_env_info('SCRIPT_NAME'), 'shop_content.php') === false &&
                !is_object($cPath) &&
                empty($product->pID) &&
                $gm_key === 'description')
            ) {
                // do nothing
            } elseif ($t_key_facebook) {
                $t_facebook_key = str_replace('facebook_', '', $gm_key);
                $t_content = $gm_value;
 
                switch ($t_facebook_key) {
                    case 'url' :
                    case 'title' :
                    case 'description' :
                        if ($t_is_product) {
                            $t_get_fb_meta = false;
                        }
                        break;
                }
 
                switch ($t_facebook_key) {
                    case 'url' :
                        $t_content = GM_HTTP_SERVER . gm_get_env_info('REQUEST_URI');
                        break;
                    case 'description' :
                        $t_content = (trim($t_content) !== '' ? trim($t_content) : trim($gm_metatags['description']));
                        break;
                }
 
                if ($t_get_fb_meta) {
                    $t_html .= "\t\t<meta property='og:{$t_facebook_key}' content='" . htmlspecialchars_wrapper($t_content) . "'/>\n";
                }
            } else {
                $t_html .= "\t\t<meta name='{$gm_key}' content='" . htmlspecialchars_wrapper($gm_value) . "' />\n";
            }
		}
		
		if ($this->output) {
			echo $t_html;
		}

		return $t_html;
	}
    
    
    /**
     * @return ConfigurationService
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function configurationService(): ConfigurationService
    {
        if ($this->configurationService === null) {
    
            $this->configurationService = LegacyDependencyContainer::getInstance()->get(ConfigurationService::class);
        }
        
        return $this->configurationService;
    }
    
    
    /**
     * @return string[]
     * @throws \Doctrine\DBAL\Exception
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function additionalMetaConfigurationKeys(): array
    {
        $connection = LegacyDependencyContainer::getInstance()->get(Connection::class);
        $query      = 'SELECT `key` FROM `gx_lang_configurations` WHERE `key` LIKE "gm_configuration/meta/%"';
        $result     = $connection->executeQuery($query)->fetchAllAssociative();
    
        return array_column($result, 'key');
    }
}
MainFactory::load_origin_class('GMMeta');
